package com.william.jdbcplus.boot.test.dao.impl;

import com.william.jdbcplus.boot.starter.util.DaoUtil;
import com.william.jdbcplus.boot.starter.wrap.QueryBootWrap;
import com.william.jdbcplus.boot.starter.wrap.QueryLambdaBootWrap;
import com.william.jdbcplus.boot.test.dao.SysDictDao;
import com.william.jdbcplus.boot.test.entity.SysDepart;
import com.william.jdbcplus.boot.test.entity.SysDict;
import com.william.jdbcplus.boot.test.entity.SysDictItem;
import com.william.jdbcplus.boot.test.entity.SysUser;
import com.william.jdbcplus.boot.test.vo.CheckVo;
import com.william.jdbcplus.boot.test.vo.DictQueryVO;
import com.william.jdbcplus.boot.test.vo.DictVO;
import com.william.jdbcplus.boot.test.vo.TreeSelectVO;
import com.william.jdbcplus.common.page.Page;
import com.william.jdbcplus.core.toolkit.StringUtil;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Repository
@AllArgsConstructor
public class SysDictDaoImpl implements SysDictDao {
    @Override
    public Long duplicateCheckCountSql(CheckVo checkVo) {
        // SELECT COUNT(*) FROM ${tableName} WHERE ${fieldName} = #{fieldVal} and id <> #{dataId}

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .select("COUNT(*)")
                .from(checkVo.getTableName())
                .eq(checkVo.getFieldName(), checkVo.getFieldVal())
                .ne("id", checkVo.getDataId());
        return bootstrap.queryOne(Long.class);
    }

    @Override
    public Long duplicateCheckCountSqlNoDataId(CheckVo checkVo) {
        // SELECT COUNT(*) FROM ${tableName} WHERE ${fieldName} = #{fieldVal}

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .select("COUNT(*)")
                .from(checkVo.getTableName())
                .eq(checkVo.getFieldName(), checkVo.getFieldVal());
        return bootstrap.queryOne(Long.class);
    }

    @Override
    public List<DictVO> queryDictItemsByCode(String code) {
        //        select s.item_value as "value",s.item_text as "text" from sys_dict_item s
        //        where dict_id = (select id from sys_dict where dict_code = #{code})
        //        order by s.sort_order asc
        QueryLambdaBootWrap bootstrap = new QueryLambdaBootWrap();
        bootstrap
                .selectAs(SysDictItem::getItemValue, DictVO::getValue)
                .selectAs(SysDictItem::getItemText, DictVO::getText)
                .from(SysDictItem.class)
                .eq(SysDictItem::getDictId, lb -> lb
                        .select(SysDict::getId)
                        .from(SysDict.class)
                        .eq(SysDict::getDictCode, code)
                )
                .orderByAsc(SysDictItem::getSortOrder);

        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<DictVO> queryTableDictItemsByCode(String table, String text, String code) {
        // select ${text} as "text",${code} as "value" from ${table}

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "text")
                .selectAs(code, "value")
                .from(table);
        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<DictVO> queryTableDictItemsByCodeAndFilter(String table, String text, String code, String filterSql) {
        //        select ${text} as "text",${code} as "value" from ${table}
        //		<if test="filterSql != null and filterSql != ''">
        //                where ${filterSql}
        //		</if>

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "text")
                .selectAs(code, "value")
                .from(table);
        if (StringUtil.isNotBlank(filterSql)) {
            bootstrap.connect(filterSql);
        }
        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public String queryDictTextByKey(String code, String key) {
        //        select s.item_text from sys_dict_item s
        //        where s.dict_id = (select id from sys_dict where dict_code = #{code})
        //        and s.item_value = #{key}

        QueryLambdaBootWrap bootstrap = new QueryLambdaBootWrap();
        bootstrap
                .select(SysDictItem::getItemText)
                .from(SysDictItem.class)
                .eq(SysDictItem::getDictId, lb -> lb
                        .select(SysDict::getId)
                        .eq(SysDict::getDictCode, code)
                )
                .eq(SysDictItem::getItemValue, key);

        return bootstrap.queryOne(String.class);
    }

    @Override
    public String queryTableDictTextByKey(String table, String text, String code, String key) {
        // select ${text} as "text" from ${table} where ${code}= #{key}

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "text")
                .from(table)
                .eq(code, key);

        return bootstrap.queryOne(String.class);
    }

    @Override
    public List<DictVO> queryTableDictByKeys(String table, String text, String code, String[] keyArray) {
        //        select ${text} as "text", ${code} as "value" from ${table} where ${code} in
        //                <foreach item="key" collection="keyArray" open="(" separator="," close=")">
        //			#{key}
        //		</foreach>

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "text")
                .selectAs(code, "value")
                .from(table)
                .in(code, Arrays.asList(keyArray));

        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<DictVO> queryAllDepartBackDictModel() {
        // select id as "value",depart_name as "text" from sys_depart where del_flag = '0'
        QueryLambdaBootWrap bootstrap = new QueryLambdaBootWrap();
        bootstrap
                .selectAs(SysDepart::getId, DictVO::getValue)
                .selectAs(SysDepart::getDepartName, DictVO::getText)
                .from(SysDepart.class)
                .eq(SysDepart::getDelFlag, "0");

        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<DictVO> queryAllUserBackDictModel() {
        // select username as "value",realname as "text" from sys_user where del_flag = '0'
        QueryLambdaBootWrap bootstrap = new QueryLambdaBootWrap();
        bootstrap
                .selectAs(SysUser::getUsername, DictVO::getValue)
                .selectAs(SysUser::getRealname, DictVO::getText)
                .from(SysUser.class)
                .eq(SysUser::getDelFlag, "0");

        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<DictVO> queryTableDictItems(String table, String text, String code, String keyword) {
        // select ${text} as "text",${code} as "value" from ${table} where ${text} like #{keyword}

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "text")
                .selectAs(code, "value")
                .from(table)
                .like(text, keyword);

        return bootstrap.queryList(DictVO.class);
    }

    @Override
    public List<TreeSelectVO> queryTreeList(Map<String, String> query, String table, String text, String code, String pidField, String pid, String hasChildField) {
        //        select ${text} as "title",
        //                ${code} as "key",
        //			   <if test="hasChildField != null and hasChildField != ''">
        //                (case when ${hasChildField} = '1' then 0 else 1 end) as isLeaf,
        //			   </if>
        //        ${pidField} as parentId
        //        from ${table}
        //        where
        //                <choose>
        //				   <when test="pid != null and pid != ''">
        //                ${pidField} = #{pid}
        //				   </when>
        //				   <otherwise>
        //                (${pidField} = '' OR ${pidField} IS NULL)
        //				   </otherwise>
        //			   </choose>
        //			   <if test="query!= null">
        //				   <foreach collection="query.entrySet()" item="value"  index="key" >
        //                and ${key} = #{value}
        //				   </foreach>
        //			   </if>

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(text, "title")
                .selectAs(code, "key")
                .selectAs(pidField, "parentId")
                .from(table);

        if (StringUtil.isNotBlank(hasChildField)) {
            if (hasChildField.equals("1")) {
                bootstrap.select("0 as isLeaf");
            } else {
                bootstrap.select("1 as isLeaf");
            }
        }

        if (StringUtil.isNotBlank(pid)) {
            bootstrap.eq(pidField, pid);
        } else {
            bootstrap.connect("({0} = '' OR {1} IS NULL)", pidField, pidField);
        }

        if (query != null) {
            for (Map.Entry<String, String> entry : query.entrySet()) {
                bootstrap.eq(entry.getKey(), entry.getValue());
            }
        }

        return bootstrap.queryList(TreeSelectVO.class);
    }

    @Override
    public void deleteOneById(String id) {
        // @Select("delete from sys_dict where id = #{id}")
        DaoUtil.BASE.deleteById(id, SysDict.class);
    }

    @Override
    public List<SysDict> queryDeleteList() {
        // @Select("select * from sys_dict where del_flag = 1")
        return DaoUtil.BASE.listAll(SysDict.class);
    }

    @Override
    public void updateDictDelFlag(int delFlag, String id) {
        // @Update("update sys_dict set del_flag = #{flag,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR}")
        SysDict sysDict = new SysDict();
        sysDict.setDelFlag(delFlag);
        sysDict.setId(id);
        DaoUtil.BASE.updateById(sysDict);
    }

    @Override
    public Page<DictVO> queryDictTablePageList(Page page, DictQueryVO query) {
        //        select ${query.text} as "text",${query.code} as "value" from ${query.table}
        //        where 1 = 1
        //                <if test="query.keyword != null and query.keyword != ''">
        //                and (${query.text} like '%${query.keyword}%' or ${query.code} like '%${query.keyword}%')
        //		</if>
        //		<if test="query.codeValue != null and query.codeValue != ''">
        //                and ${query.code} = #{query.codeValue}
        //		</if>

        QueryBootWrap bootstrap = new QueryBootWrap();
        bootstrap
                .selectAs(query.getText(), "text")
                .selectAs(query.getCode(), "value")
                .from(query.getTable());

        if (StringUtil.isNotBlank(query.getKeyword())) {
            bootstrap.like(query.getText(), query.getKeyword()).or().like(query.getCode(), query.getKeyword());
        }

        if (StringUtil.isNotBlank(query.getCodeValue())) {
            bootstrap.eq(query.getCode(), query.getCodeValue());
        }

        Page<DictVO> result = bootstrap.queryPage(page, DictVO.class);
        return result;
    }
}
